import commonConstants from "@/common/commonConstants";
import commonMethod from "@/common/commonMethod";
import { Cartesian3 } from "cesium";

/**
 * 决策者，对任务进行处理
 */
class DecisionMaker{
    constructor(){
        this.decisionLinks = [];
        this.taskDecisionSource = new Map()
        
        this._initTaskTypeSource();
    }

    /**
     * 初始化认为的决策组
     */
    _initTaskTypeSource(){
        this.taskDecisionSource.set(commonConstants.taskType.detection,[
            this.getDecisionByType(commonConstants.decisionType.proximity),
            this.getDecisionByType(commonConstants.decisionType.detection),
            this.getDecisionByType(commonConstants.decisionType.turn_back)
        ])

        this.taskDecisionSource.set(commonConstants.taskType.detection,[
            this.getDecisionByType(commonConstants.decisionType.proximity),
            this.getDecisionByType(commonConstants.decisionType.hit_out),
            this.getDecisionByType(commonConstants.decisionType.turn_back)
        ])
    }


    /**
     * 默认的根据任务生成的决策链，是为了方便
     * @param {Task} task 
     */
    handleTask(task){   
        const options = {
            task: task,
            troop:task.getTroop(),
            target:task.getTarget()
        }
        if(task.getTaskType() == commonConstants.taskType.detection){
            options.decisions = this.taskDecisionSource.get(commonConstants.taskType.detection);     
        }else if (task.getTaskType() == commonConstants.taskType.strike) {
           options.decisions = this.taskDecisionSource.get(commonConstants.taskType.strike);
        }

        return new DecisionLink(options);

    }

    /**
     * 根据决策单元生成决策链，可以不针对任务
     * @param {Array} ds 指定决策类型的数组
     */
    craeteDecisionLink(ds,troop,target){
       
        return new DecisionLink({
            troop : troop,
            target:target,
            decisions: ds.map(d=> this.getDecisionByType(d))
        });
    }

    getDecisionByType(t){
        let decision = undefined;
        if (t == commonConstants.decisionType.detection) {
            decision = new DetectionDecision();
        }else if (t == commonConstants.decisionType.proximity) {
            decision = new ProximityDecision();
        }else if (t == commonConstants.decisionType.turn_back) {
            decision = new TurnBackDecision();
        }
        return decision;
    }
}


/**
 * 任务信息，任务的基本信息
 */
class Task{
    constructor(ops){
        this.taskId = commonMethod.creatUUID();
        this.taskName = "未命名";
        this.taskType = undefined;
        this.startTime = undefined;
        this.endTiem - undefined;

    }
}


class DecisionLink{
    constructor(ops){
        this.task = undefined;
        this.troop = undefined;
        this.target = undefined;
        this.decisions = [];
        this.fristDecision = undefined;
        this.lastDecison = undefined;
        this.curDecision = undefined;

        this.isDone = false;
        if (ops) {
            if (ops["task"]) {
                this.task = ops["task"]
            }
            if (ops["troop"]) {
                this.troop = ops["troop"]
            }
            if (ops["target"]) {
                this.target = ops["target"]
            }
            if (ops["decisions"]) {
                this.decisions = ops["decisions"]
            }
        }

        if (this.decisions && this.decisions.length >0) {
            this.decisions.forEach(d => {
                d.setTroop(this.troop);
                d.setTarget(this.target);
                this.addDecision(d);
            });
        }
    }

    addDecision(d){
        this.decisions.push(d);
        if (!this.fristDecision) {
            this.fristDecision = d;
        }else{
            this.lastDecison.next = d;
            d.per = this.lastDecison
        }
        this.lastDecison = d;
    }
    getDone(){
        return this.isDone;
    }

    /**
     * 决策处理
     */
    decisionProcessing(s,t){
        if (this.lastDecison.getDone()) {
           this.isDone = true;
           return
        }
        this.curDecision = this.fristDecision;
        while (this.curDecision) {
            if (this.curDecision.getDone()) {
                this.curDecision = this.curDecision.next;
                continue;
            }
            const flag = this.curDecision.decisionTrigger(s,t);
            if (flag) {
                this.curDecision.decisionEvent(t);
            }
            this.curDecision = this.curDecision.next;
        }
    }
}

/**
 * 决策体，可以形成决策链，
 */
class Decision{
    constructor(){
        this.next = undefined;
        this.per = undefined;
        //决策是否完成
        this.isDone = false;

        this.troop = undefined;
        this.target = false;
    }

    setTroop(t){
        this.troop = t;
    }

    setTarget(tg){
        this.target = tg;
    }


    /**
     * 触发条件
     * @param  s 
     * @param  t 
     */
    decisionTrigger(s,t){
        return this.per? this.per.getDone():true;
    }

    /**
     * 触发兵力的动作
     */
    decisionEvent(t){

    }
    
    getDone(){
        return this.isDone;
    }
}


/**
 * 探测
 */
class DetectionDecision extends Decision{
    constructor(){
        super();
    }

     /**
     * 触发兵力的动作
     */
     decisionEvent(t){
        // console.log("探测完成");
        //探测距离
        let dis = this.troop.detectionDistance
        let staticPos = this.target;
        if(this.target.className && this.target.className == "Influence"){
            //影响体
            dis += this.target.influenceRaill
            staticPos = this.target.influenceCenter
        }else if (this.target.className && this.target.className == "Troop") {
            staticPos = this.target.getStaticPosition()
        }

        const pos = this.troop.getEntity().position.getValue(t)
        const distance = Cartesian3.distance(pos,staticPos);
        if (distance <= dis) {
            this.isDone = true;
        }
       
    }
}


/**
 * 靠近的决策元
 */
class ProximityDecision extends Decision{

    constructor(){
        super()
    }
    /**
     * 触发兵力的动作
     */
    decisionEvent(t){  
        // super()
        // console.log("靠近完成");
        //改变航行方向
        //计算起始点和当前点的夹角
        const pos = this.troop.getEntity().position.getValue(t);

        let staticPos = this.target;
        if (this.target.className && this.target.className == "Troop") {
            staticPos = this.target.getStaticPosition();
        }else if(this.target.className && this.target.className == "Influence"){
            staticPos = this.target.influenceCenter;
        }
        const angle = commonMethod.costIncludedAngle(pos,staticPos);
        //设置航行方向
        this.troop.heading = angle;

        this.isDone = true;
    }


}

/**
 * 返航的决策元
 */
class TurnBackDecision extends Decision{
    constructor(){
        super();
    }

    /**
     * 触发兵力的动作
     */
    decisionEvent(t){
        // super()
        // console.log("返回完成");
       //改变航行方向
        //计算起始点和当前点的夹角
        const pos = this.troop.getEntity().position.getValue(t);
        const staticPos = this.troop.getStaticPosition();
        const angle = commonMethod.costIncludedAngle(pos,staticPos);
        //设置航行方向
        this.troop.heading = angle;
        this.isDone = true;
    }


}


export default DecisionMaker;
 

